﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using LitJson;

[ExecuteInEditMode]
public abstract class PUEXAffector : MonoBehaviour {

	protected static int __spawnIndex = 0;

	#region - Editable property
	public string affectorName = "";
	#endregion
	
	#region - Property
	[HideInInspector]
	public bool autoStart;
	[HideInInspector]
	protected bool _enabled;
	public bool isEnabled () {
		return _enabled;
	}
	public virtual void enable () {
		_enabled = true;
	}
	public virtual void disable () {
		_enabled = false;

		_triggerDuration = 0f;
		_triggerDurationRemain = 0f;
		triggerTimeFraction = 0f;
	}

	protected float _triggerDuration;
	protected float _triggerDurationRemain;
	[HideInInspector]
	public float triggerTimeFraction;
	public bool inTrigger () {
		return _triggerDuration > 0f;
	}

	[HideInInspector]
	public PUEXEmitter ownerEmitter;
	#endregion
	
	#region - Lifecycle
	public PUEXAffector () 
	{
		autoStart = true;
		_enabled = false;
		_triggerDuration = 0f;
		_triggerDurationRemain = 0f;
		triggerTimeFraction = 0f;
		ownerEmitter = null;
	}

	public void Reset ()
	{
		// need emitter
		var emitter = gameObject.GetComponent<PUEXEmitter> ();
		if (emitter == null)
		{
			Debug.LogError("<PUEX> no emitter with affector");
		}
		
		if (affectorName.Length == 0) {
			string typeName = GetType().Name;
			typeName = typeName.Replace("PUEX", "");
			typeName = typeName.Replace("Affector", "");
			affectorName = gameObject.name + " " + typeName + " " + ++__spawnIndex;
		}
	}

	public void OnEnable ()
	{
		if (Application.isPlaying) {
			enable ();
		} else {
			autoStart = true;
		}
	}
	
	public void OnDisable ()
	{
		if (Application.isPlaying) {
			disable ();
		} else {
			autoStart = false;
		}
	}
	#endregion

	#region - State
	public virtual void prepared(PUEXEmitter emitter)
	{
		this.ownerEmitter = emitter;
	}
	
	public virtual void start ()
	{
		if (autoStart)
			enable ();
	}
	
	public virtual void pause ()
	{
	}
	
	public virtual void resume ()
	{
	}
	
	public virtual void stop ()
	{
		disable ();
	}
	
	public virtual void unPrepared()
	{
	}
	#endregion
	
	#region - Update
	public virtual void preUpdate (float dt)
	{
	}

	public virtual void update (float dt, PUEXParticle particle)
	{
	}

	public virtual void postUpdate (float dt)
	{
		if (inTrigger ()) {
			_triggerDurationRemain -= dt;
			triggerTimeFraction = (_triggerDuration - _triggerDurationRemain) / _triggerDuration;
			if (_triggerDurationRemain <= 0f) {
				disable ();
			}
		}
	}
	#endregion

	#region - Event
	public virtual void trigger (float duration)
	{
		if (_enabled == false) {
			_triggerDuration = duration;
			_triggerDurationRemain = duration;
			triggerTimeFraction = 0f;

			enable ();
		}
	}
	#endregion
	
	#region - Param property
	public virtual void updateParams (PUEXParticleSystem system)
	{
	}
	#endregion

	#region - Serialization
	public virtual JsonData save (JsonData emitterData, JsonData systemData)
	{
		JsonData ret = new JsonData ();
		
		ret ["type"] = GetType ().Name;
		ret ["name"] = affectorName;
		ret ["auto_start"] = enabled;

		return ret;
	}
	#endregion
	
}
